﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: LGPL, Software Libre	*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
using ESF.General;
using ESF.General.Entity;

#endregion


namespace ESF.WinForms
{
	public static class WinFormsHelper
	{
		#region General

		public static void CloseApplication ()
		{
			Environment.Exit (0);
		}


		public static void ShowAtCenter (Form pWindow)
		{
			int boundWidth = Screen.PrimaryScreen.Bounds.Width;
			int boundHeight = Screen.PrimaryScreen.Bounds.Height;

			int x = (int) (boundWidth - pWindow.Width);
			int y = (int) (boundHeight - pWindow.Height);

			pWindow.Location = new System.Drawing.Point (x / 2, y / 2);
		}

		#endregion


		#region Asignadores

		public static string GetText(Control pControl)
		{
			return pControl.Invoke ((Func<string>)delegate() { return pControl.Text; }) as string;
		}


		public static void SetText (Control pLabel, string pMessage)
		{
			pLabel.Invoke ((Action) delegate () { pLabel.Text = pMessage; });
		}


		public static void ClearText (Control pLabel)
		{
			pLabel.Invoke ((Action) delegate () { pLabel.Text = string.Empty; });
		}


		public static void SetAdvance(Control pLabel, ProgressBar pProgressBar, string pMessage = "", int pTotalWorkCount = 0, int pReadyWorkCount = 0, int pTotalErrors = 0, long pItemElapsedMs = 0)
		{
			double advance100;


			advance100 = ProcessHelper.GetAdvancePercentage100 (pTotalWorkCount, pReadyWorkCount + pTotalErrors);

			SetText (pLabel, 
				(string.IsNullOrEmpty (pMessage) ? string.Empty : pMessage + "... ") + 
				string.Format ("Procesados {0} de {1}{3}: {2:0.##}%", pReadyWorkCount, pTotalWorkCount, advance100, 
				(pTotalErrors > 0 ? string.Format (" con {0} errores", pTotalErrors) : string.Empty)));
			
			SetValue (pProgressBar, advance100);
		}


		public static void ClearAdvance (Control pLabel, ProgressBar pProgressBar)
		{
			ClearText (pLabel);
			ClearValue (pProgressBar);
		}


		public static void ClearValue (ProgressBar pProgressBar)
		{
			SetValue (pProgressBar, 0);
		}


		public static void SetValue (ProgressBar pProgressBar, double pValue)
		{
			pProgressBar.Invoke ((Action) delegate () { pProgressBar.Value = (int) pValue; });
		}

		#endregion


		#region Imagenes

		public static BitmapSource ToBitmapSource (Bitmap pImage)
		{
			return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
			   pImage.GetHbitmap (),
			   IntPtr.Zero,
			   System.Windows.Int32Rect.Empty,
			   BitmapSizeOptions.FromEmptyOptions ()); 
		}

		#endregion

		
		#region Mensajes
		
		public static void SetDefaultUnhanledExceptionManagers ()
		{
			Log.SetDefaultUnhanledExceptionManagers ();

			System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Log.Application_ThreadException);
			
			System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
		}


		public static void ShowError (ContainerControl pOwner, Exception pEx)
		{
			ShowError (pOwner, null, pEx);
		}


		public static void ShowError (ContainerControl pOwner, string pMessage, Exception pEx)
		{
			Log.Error (pMessage, pEx);

			if (string.IsNullOrEmpty (pMessage))
			{
				ShowError (pOwner, GenericException.GetClientMessage (pEx));
			}
			else
			{
				ShowError (pOwner, pMessage);
			}
		}


		public static void ShowError (ContainerControl pOwner, string pMessage)
		{
			pOwner.Invoke (new Action (delegate ()
			{
				System.Windows.Forms.MessageBox.Show (pOwner, pMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
			}));
		}
		
		
		public static void ShowInfo (ContainerControl pOwner, string pMessage)
		{
			pOwner.Invoke (new Action (delegate ()  
			{
				System.Windows.Forms.MessageBox.Show (pOwner, pMessage, "Información", MessageBoxButtons.OK, MessageBoxIcon.Information); 
			}));
		}


		public static void SetVisible (Control pControl, bool pVisible = true)
		{
			pControl.Invoke(new Action(delegate()
			{
				pControl.Visible = pVisible;
			}));
		}


		public static void SetEnabled(Control pControl, bool pEnabled = true)
		{
			pControl.Invoke(new Action(delegate()
			{
				pControl.Enabled = pEnabled;
			}));
		}


		public static bool ShowConfirm (ContainerControl pOwner, string pMessage)
		{
			DialogResult result;
			
			
			result = System.Windows.Forms.MessageBox.Show (pOwner, pMessage, "Confirmación", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

			if (result == DialogResult.OK || result == DialogResult.Yes)
			{
				return true;
			}

			return false;
		}


		public static void ShowWarning (ContainerControl pOwner, string pMessage)
		{
			pOwner.Invoke (new Action (delegate ()  
			{
				System.Windows.Forms.MessageBox.Show (pOwner, pMessage, "Advertencia de la Aplicación", MessageBoxButtons.OK, MessageBoxIcon.Warning); 
			}));
		}
		
		#endregion
		
		
		#region Menu
		
		public static void ClearMenu (MenuStrip pMenu)
		{
			pMenu.Items.Clear ();
		}
		
		
		public static bool LoadMenu (MenuStrip pMenu, List<UserMenuItem> pMenuItems, EventHandler pClickHandler)
		{
			List<LeafTreeItem<UserMenuItem>> treeMenuItems;
			
			LeafTreeItem <UserMenuItem> currentLevel;
			
			
			if (pMenuItems == null || pMenuItems.Count == 0) { ClearMenu (pMenu); return false; }
			
			
			treeMenuItems = new List<LeafTreeItem<UserMenuItem>> ();
			
			
			foreach (UserMenuItem root in pMenuItems.FindAll (mi => mi.Parent == null))
			{
				currentLevel = new LeafTreeItem<UserMenuItem> (root);
				
				AddChildren (currentLevel, pMenuItems);
				
				treeMenuItems.Add (currentLevel);
			}
			
			
			return LoadMenu (pMenu, treeMenuItems, pClickHandler);
		}
		
		
		private static void AddChildren (LeafTreeItem<UserMenuItem> pParentItem, List<UserMenuItem> pMenuItems)
		{
			LeafTreeItem <UserMenuItem> currentLevel;
			
			
			foreach (UserMenuItem item in pMenuItems.FindAll (mi => mi.Parent != null && mi.Parent.Equals (pParentItem.Content)))
			{
				currentLevel = new LeafTreeItem<UserMenuItem> (item);
			
				AddChildren (currentLevel, pMenuItems);
			
				pParentItem.Children.Add (currentLevel);
			}
		}
		
		
		public static bool LoadMenu (MenuStrip pMenu, List<LeafTreeItem<UserMenuItem>> pTreeMenuItems, EventHandler pClickHandler)
		{
			if (pTreeMenuItems == null || pTreeMenuItems.Count == 0) { ClearMenu (pMenu); return false; }
			
			foreach (LeafTreeItem<UserMenuItem> i in pTreeMenuItems)
			{
				pMenu.Items.Add (ConvertToMenuItem (i, pClickHandler));
			}
			
			return true;
		}
		
		
		private static ToolStripMenuItem ConvertToMenuItem (LeafTreeItem<UserMenuItem> pItemTree, EventHandler pClickHandler)
		{
			ToolStripMenuItem item;
			
			
			item = new ToolStripMenuItem (pItemTree.Content.Name);
			item.Name = pItemTree.Content.Code;
			item.ToolTipText = pItemTree.Content.Description;
			item.Click += pClickHandler;
			
			foreach (LeafTreeItem<UserMenuItem> i in pItemTree.Children)
			{
				item.DropDownItems.Add (ConvertToMenuItem (i, pClickHandler));
			}
			
			return item;
		}
		
		#endregion
	}
}
